<!DOCTYPE html>
<html>
<head>
    <title>Mechanical Manipulator Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #fff;
        }
    </style>
</head>
<body>
    <canvas id="manipulatorCanvas" width="950" height="550"></canvas>

    <script>
        const canvas = document.getElementById('manipulatorCanvas');
        const ctx = canvas.getContext('2d');

        /**
         * Draws an arrow from one point to another.
         * @param {CanvasRenderingContext2D} ctx - The canvas context.
         * @param {number} fromx - The x-coordinate of the start point.
         * @param {number} fromy - The y-coordinate of the start point.
         * @param {number} tox - The x-coordinate of the end point.
         * @param {number} toy - The y-coordinate of the end point.
         * @param {number} headlen - The length of the arrow head.
         */
        function drawArrow(ctx, fromx, fromy, tox, toy, headlen) {
            const dx = tox - fromx;
            const dy = toy - fromy;
            const angle = Math.atan2(dy, dx);
            ctx.beginPath();
            ctx.moveTo(fromx, fromy);
            ctx.lineTo(tox, toy);
            ctx.stroke();
            ctx.beginPath();
            ctx.moveTo(tox, toy);
            ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(tox, toy);
            ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
        }

        // --- Drawing Parameters ---
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 3;
        ctx.font = 'bold 30px serif';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        
        // --- Define Geometry ---
        // Using relative lengths to define coordinates
        const scale = 550;
        const l_AB = 0.8 * scale;
        const l_AE = 0.2 * scale;
        const l_BC = 0.5 * scale;
        const l_CD = 0.3 * scale;

        const Ax = 150, Ay = 200;
        const Ex = Ax + l_AE, Ey = Ay;
        const Bx = Ax + l_AB, By = Ay;

        const angleB_deg = 30;
        const angleB_rad = angleB_deg * Math.PI / 180;
        const Cx = Bx + l_BC * Math.cos(angleB_rad);
        const Cy = By + l_BC * Math.sin(angleB_rad);

        const angleC_deg = 30;
        const angleC_rad_rel = angleC_deg * Math.PI / 180;
        const angleC_rad_abs = angleB_rad + angleC_rad_rel; // Total angle from horizontal
        const Dx = Cx + l_CD * Math.cos(angleC_rad_abs);
        const Dy = Cy + l_CD * Math.sin(angleC_rad_abs);
        
        // --- Draw Components ---

        // 1. Pivot at A
        ctx.beginPath();
        ctx.moveTo(Ax - 30, Ay + 10);
        ctx.lineTo(Ax, Ay - 30);
        ctx.lineTo(Ax + 30, Ay + 10);
        ctx.closePath();
        ctx.stroke();
        
        const groundY = Ay + 10;
        ctx.beginPath();
        ctx.moveTo(Ax - 45, groundY);
        ctx.lineTo(Ax + 45, groundY);
        ctx.stroke();
        for (let i = Ax - 40; i <= Ax + 40; i += 10) {
            ctx.beginPath();
            ctx.moveTo(i, groundY);
            ctx.lineTo(i - 10, groundY + 10);
            ctx.stroke();
        }
        ctx.fillText('A', Ax - 35, Ay - 15);

        // 2. Links
        ctx.lineWidth = 5;
        ctx.beginPath();
        ctx.moveTo(Ax, Ay);
        ctx.lineTo(Bx, By); // Link AEB
        ctx.moveTo(Bx, By);
        ctx.lineTo(Cx, Cy); // Link BC
        ctx.moveTo(Cx, Cy);
        ctx.lineTo(Dx, Dy); // Link CD
        ctx.stroke();
        ctx.lineWidth = 3;

        // 3. Joints (open circles)
        [ [Ax, Ay], [Bx, By], [Cx, Cy] ].forEach(([x, y]) => {
            ctx.beginPath();
            ctx.arc(x, y, 8, 0, 2 * Math.PI);
            ctx.fillStyle = 'white';
            ctx.fill();
            ctx.stroke();
        });

        // 4. Force F
        const fAngle_deg = 180 - 30;
        const fAngle_rad = fAngle_deg * Math.PI / 180;
        const fLength = 100;
        const Fx_start = Ex + fLength * Math.cos(fAngle_rad);
        const Fy_start = Ey + fLength * Math.sin(fAngle_rad);
        
        ctx.lineWidth = 4;
        drawArrow(ctx, Fx_start, Fy_start, Ex, Ey, 20);
        ctx.lineWidth = 3;

        // Angle indicator for F
        const indicatorPointOnForceX = Ex + 40 * Math.cos(fAngle_rad);
        const indicatorPointOnForceY = Ey + 40 * Math.sin(fAngle_rad);
        ctx.beginPath();
        ctx.moveTo(indicatorPointOnForceX, Ey);
        ctx.lineTo(indicatorPointOnForceX, indicatorPointOnForceY);
        ctx.stroke();
        
        // 5. Angle at B
        ctx.save();
        ctx.lineWidth = 2;
        ctx.setLineDash([6, 4]);
        ctx.beginPath();
        ctx.moveTo(Bx, By);
        ctx.lineTo(Bx + 90, By);
        ctx.stroke();
        ctx.restore();
        ctx.beginPath();
        ctx.arc(Bx, By, 50, 0, angleB_rad);
        ctx.stroke();
        
        // 6. Angle at C
        ctx.save();
        ctx.lineWidth = 2;
        ctx.setLineDash([6, 4]);
        ctx.beginPath();
        ctx.moveTo(Cx, Cy);
        ctx.lineTo(Cx + 70 * Math.cos(angleB_rad), Cy + 70 * Math.sin(angleB_rad));
        ctx.stroke();
        ctx.restore();
        ctx.beginPath();
        ctx.arc(Cx, Cy, 45, angleB_rad, angleC_rad_abs);
        ctx.stroke();
        
        // 7. Gripper at D
        ctx.lineWidth = 4;
        const gripAngle = angleC_rad_abs - Math.PI / 2;
        ctx.save();
        ctx.translate(Dx, Dy);
        ctx.rotate(gripAngle);
        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.lineTo(15, 0);
        ctx.stroke();
        ctx.beginPath();
        ctx.moveTo(15, -18);
        ctx.lineTo(15, 18);
        ctx.stroke();
        ctx.beginPath();
        ctx.moveTo(15, 18);
        ctx.lineTo(28, 18);
        ctx.lineTo(28, 8);
        ctx.stroke();
        ctx.restore();

        // 8. Labels
        ctx.fillStyle = 'black';
        ctx.fillText('F', Fx_start - 20, Fy_start - 20);
        ctx.fillText('30°', Ex - 65, Ey - 25);
        ctx.fillText('E', Ex, Ey - 25);
        ctx.fillText('B', Bx + 25, By - 15);
        ctx.fillText('30°', Bx + 65, By + 30);
        ctx.fillText('C', Cx + 25, Cy + 15);
        
        const textAngleC = angleB_rad + angleC_rad_rel / 2;
        ctx.fillText('30°', Cx + 60 * Math.cos(textAngleC), Cy + 60 * Math.sin(textAngleC));
        ctx.fillText('D', Dx - 15, Dy + 30);

    </script>
</body>
</html>